#include "algtestform.h"
#include "ui_algtestform.h"

#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QScreen>
#include <QSettings>
#include <QTextCodec>
#include <QDebug>

AlgTestForm::AlgTestForm(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::AlgTestForm)
{
    ui->setupUi(this);
    m_nCameraIndex = 0;
    m_roi = 0;

    // 列表控件配置
    ui->listWidget->setViewMode(QListWidget::IconMode);
    ui->listWidget->setIconSize(QSize(240, 240));  // 大图标尺寸
    ui->listWidget->setResizeMode(QListWidget::Adjust);
    ui->listWidget->setGridSize(QSize(260, 260));   // 网格稍大于图标，避免重叠
    ui->listWidget->setSpacing(10);                 // 增加间距

    ui->Bt_draw_roi->setEnabled(false);
    ui->Bt_retest->setEnabled(false);
    ui->Bt_save_roi->setEnabled(false);
    ui->Bt_save_roi->hide();
    RdConfig(0);
}

AlgTestForm::~AlgTestForm()
{
    delete ui;
}

void AlgTestForm::RdConfig(int index)
{
    QString Path = "configs/configs.ini";
    QSettings iniRead(Path, QSettings::IniFormat);
    iniRead.setIniCodec(QTextCodec::codecForName("UTF_8"));

    int x = iniRead.value(QString("Roi_setting_%1/x").arg(index+1)).toInt();
    int y = iniRead.value(QString("Roi_setting_%1/y").arg(index+1)).toInt();
    int w = iniRead.value(QString("Roi_setting_%1/width").arg(index+1)).toInt();
    int h = iniRead.value(QString("Roi_setting_%1/height").arg(index+1)).toInt();

    m_qRect.setRect(x,y,w,h);
}

void AlgTestForm::WdConfig(int index)
{
    QString Path = "configs/configs.ini";
    QSettings iniWrite(Path, QSettings::IniFormat);
    iniWrite.setIniCodec(QTextCodec::codecForName("UTF_8"));
    QRect rect;
    switch (index) {
    case 0:
        rect = ui->label_2->getROI();
        break;
    case 1:
        rect = ui->label_2->getROI();
        break;
    }
    // qDebug() << rect.x() << rect.y() << rect.width() << rect.height();
    iniWrite.setValue(QString("Roi_setting_%1/x").arg(index+1), rect.x());
    iniWrite.setValue(QString("Roi_setting_%1/y").arg(index+1), rect.y());
    iniWrite.setValue(QString("Roi_setting_%1/width").arg(index+1), rect.width());
    iniWrite.setValue(QString("Roi_setting_%1/height").arg(index+1), rect.height());
}


void AlgTestForm::handleAlgorithmResult(QImage result)
{
    if (!result.isNull()){
        ui->label->setPixmap(QPixmap::fromImage(result));
    }
}



#include <Alg/Api_WoodDetect.h>
// 定义检测结果结构
struct DetectionInfo {
    unsigned int* x1 = nullptr;
    unsigned int* y1 = nullptr;
    unsigned int* x2 = nullptr;
    unsigned int* y2 = nullptr;
    unsigned int* cls = nullptr;
    size_t count = 0;

    // 构造函数
    DetectionInfo() = default;

    // 析构函数，自动释放内存
    ~DetectionInfo() {
        clear();
    }

    // 清除分配的内存
    void clear() {
        if (x1) free(x1);
        if (y1) free(y1);
        if (x2) free(x2);
        if (y2) free(y2);
        if (cls) free(cls);
        x1 = y1 = x2 = y2 = cls = nullptr;
        count = 0;
    }

    // 获取指定索引的边界框
    cv::Rect getBBox(size_t index) const {
        if (index >= count || !x1) {
            return cv::Rect();
        }
        return cv::Rect(
            x1[index],
            y1[index],
            x2[index] - x1[index],
            y2[index] - y1[index]
            );
    }
};


void AlgTestForm::processAreaCameraImage(const cv::Mat &dst)
{
    cv::Mat cvImage = dst.clone();
    int x = m_qRect.x();
    int y = m_qRect.y();
    int width = m_qRect.width();
    int height = m_qRect.height();

    // 创建OpenCV的Rect对象

    cv::Rect cvRect(x, y, width, height);
    cv::Mat src = cvImage(cvRect);
    cv::cvtColor(src, src, cv::COLOR_BGR2RGB);

    if (src.empty()) {
        QMessageBox::warning(nullptr, "Wrong", "Unable to read the image file!");
        return;
    }


    DetectionInfo detections;

    // 调用CameraFunc函数
    // Obj<WoodInterFace>::GetInstance()->CameraFunc(
    //     static_cast<void*>(src.data),
    //     static_cast<unsigned int>(src.cols),
    //     static_cast<unsigned int>(src.rows),
    //     0.5, // gamma值
    //     detections.x1,
    //     detections.y1,
    //     detections.x2,
    //     detections.y2,
    //     detections.cls
    //     );

    if (detections.x1) {
        size_t totalSize = _msize(detections.x1); // 获取分配的内存总字节数
        detections.count = totalSize / sizeof(unsigned int);

        // qDebug() << "Detected" << detections.count << "object";
    }
    else {
        qDebug() << "No objects have been detected.";
    }

    if (detections.count > 0) {
        std::vector<cv::Scalar> colors = {
            cv::Scalar(0, 0, 255),    // 红色
            cv::Scalar(0, 255, 0),    // 绿色
            cv::Scalar(255, 0, 0),    // 蓝色
            cv::Scalar(0, 255, 255),  // 黄色
            cv::Scalar(255, 0, 255)   // 粉色
        };

        for (size_t i = 0; i < detections.count; i++) {
            // 获取边界框
            cv::Rect bbox = detections.getBBox(i);

            // 获取类别和颜色
            unsigned int classId = detections.cls[i];
            cv::Scalar color = colors[classId % colors.size()];

            // 绘制矩形边界框
            cv::rectangle(src, bbox, color, 2);

            // 创建类别文本
            std::string label = "Class: " + std::to_string(classId);

            // 绘制文本背景
            cv::rectangle(
                src,
                cv::Point(bbox.x, bbox.y - 20),
                cv::Point(bbox.x + label.size() * 10, bbox.y),
                color,
                cv::FILLED
                );

            // 绘制文本
            cv::putText(
                src,
                label,
                cv::Point(bbox.x, bbox.y - 5),
                cv::FONT_HERSHEY_SIMPLEX,
                0.5,
                cv::Scalar(255, 255, 255), // 白色文本
                1
                );

            qDebug() << "Object" << i << ": "
                     << "Coordinates(" << bbox.x << "," << bbox.y << ")"
                     << "Size(" << bbox.width << "x" << bbox.height << ")"
                     << "Category:" << classId;
        }
    }

    QImage qImage(
        src.data,
        src.cols,
        src.rows,
        static_cast<int>(src.step),
        QImage::Format_RGB888
        );

    QImage displayImage = qImage.copy();

    if (ui->label_3) {
        QPixmap pixmap = QPixmap::fromImage(displayImage);
        ui->label_3->setPixmap(pixmap.scaled(
            ui->label_3->size(),
            Qt::KeepAspectRatio,
            Qt::SmoothTransformation
            ));
    }
}

void AlgTestForm::on_comboBox_activated(int index)
{
    m_nCameraIndex = index;
    RdConfig(index);
}

void AlgTestForm::displayImageWithRect(const cv::Mat &dst, const QRect& rect)
{

    cv::Mat cvImage = dst.clone();

    // 转换颜色空间 BGR->RGB
    cv::cvtColor(cvImage, cvImage, cv::COLOR_BGR2RGB);

    // 绘制矩形（红色边框）
    cv::rectangle(cvImage,
                  cv::Rect(rect.x(), rect.y(), rect.width(), rect.height()),
                  cv::Scalar(255, 0, 0), 2);

    // 创建QImage
    QImage qimg(cvImage.data, cvImage.cols, cvImage.rows,
                cvImage.step, QImage::Format_RGB888);

    // 深拷贝避免指针失效
    QImage displayImage = qimg.copy();

    // 在UI中显示
    ui->label_2->setPixmap(QPixmap::fromImage(displayImage));
}

void AlgTestForm::on_Bt_open_scan_clicked()
{
    ui->listWidget->clear();
    QString folderPath = QFileDialog::getExistingDirectory(this, "select file", QDir::homePath());
    if (folderPath.isEmpty()) return;
    ui->lineEdit->setText(folderPath);
    QDir dir(folderPath);
    QStringList filters = {"*.png", "*.jpg", "*.jpeg", "*.bmp"};

    // 获取文件列表
    QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files);

    // 按文件名最后一个 "_数字" 排序
    std::sort(fileList.begin(), fileList.end(), [](const QFileInfo &a, const QFileInfo &b) {
        QString nameA = a.baseName(); // 获取文件名（不含扩展名）
        QString nameB = b.baseName();

        // 提取最后一个 "_数字" 部分
        int lastUnderscoreA = nameA.lastIndexOf('_');
        int lastUnderscoreB = nameB.lastIndexOf('_');

        if (lastUnderscoreA != -1 && lastUnderscoreB != -1) {
            QString numStrA = nameA.mid(lastUnderscoreA + 1); // 提取 "_" 后面的部分
            QString numStrB = nameB.mid(lastUnderscoreB + 1);

            bool okA, okB;
            int numA = numStrA.toInt(&okA);
            int numB = numStrB.toInt(&okB);

            if (okA && okB) { // 如果都是数字，则按数字排序
                return numA < numB;
            }
        }
        // 如果不符合格式，则按默认的字典序排序
        return nameA < nameB;
    });

    qreal dpi = screen()->devicePixelRatio();
    int targetSize = qRound(240 * dpi);
    for (const QFileInfo &fileInfo : fileList) {
        QImage image(fileInfo.absoluteFilePath());
        if (!image.isNull()) {
            QImage thumb = image.scaled(
                targetSize, targetSize,
                Qt::KeepAspectRatio,
                Qt::SmoothTransformation
                );
            if (image.width() < targetSize && image.height() < targetSize) {
                thumb = image;
            }
            QListWidgetItem *item = new QListWidgetItem(QIcon(QPixmap::fromImage(thumb)), fileInfo.fileName());
            item->setToolTip(fileInfo.fileName());
            ui->listWidget->addItem(item);
        }
    }
    emit sigAlgTestPath(fileList);
}

void AlgTestForm::on_Bt_open_area_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(
        nullptr,
        "Select the image file",
        "",
        "Image file (*.png *.jpg *.jpeg *.bmp)"
        );

    if (filePath.isEmpty()) {
        return;
    }
    QTextCodec* code = QTextCodec::codecForName("GB2312");//解决中文路径问题
    std::string strPath = code->fromUnicode(filePath).data();
    m_original = cv::imread(strPath);

    displayImageWithRect(m_original,m_qRect);
    processAreaCameraImage(m_original);
    ui->Bt_draw_roi->setEnabled(true);
    ui->Bt_retest->setEnabled(true);
    ui->Bt_save_roi->setEnabled(true);
}

void AlgTestForm::on_Bt_draw_roi_clicked()
{
    if(m_roi){
        ui->Bt_draw_roi->setText(tr("startROIDrawing"));
        ui->label_2->stopROIDrawing();
        on_Bt_save_roi_clicked();
        displayImageWithRect(m_original, m_qRect);
    }else{
        ui->Bt_draw_roi->setText(tr("stopROIDrawing"));
        QImage qimg(m_original.data, m_original.cols, m_original.rows,
            m_original.step, QImage::Format_BGR888);

        // 深拷贝避免指针失效
        QImage displayImage = qimg.copy();

        // 在UI中显示
        ui->label_2->setPixmap(QPixmap::fromImage(displayImage));
        ui->label_2->startROIDrawing();
    }
    m_roi = 1 - m_roi;
}


void AlgTestForm::on_Bt_save_roi_clicked()
{
    WdConfig(m_nCameraIndex);
    RdConfig(m_nCameraIndex);
}


void AlgTestForm::on_Bt_retest_clicked()
{
    processAreaCameraImage(m_original);
    displayImageWithRect(m_original, m_qRect);
}

